home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Browsers, Managers & Extensions / Mozilla Weave 0.2.7 / latest-weave.xpi / modules / engines / input.js < prev    next >
Text File  |  2008-08-08  |  9KB  |  296 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Bookmarks Sync.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla.
  17.  * Portions created by the Initial Developer are Copyright (C) 2008
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Anant Narayanan <anant@kix.in>
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36.  
  37. const EXPORTED_SYMBOLS = ['InputEngine'];
  38.  
  39. const Cc = Components.classes;
  40. const Ci = Components.interfaces;
  41. const Cu = Components.utils;
  42.  
  43. Cu.import("resource://weave/log4moz.js");
  44. Cu.import("resource://weave/async.js");
  45. Cu.import("resource://weave/util.js");
  46. Cu.import("resource://weave/engines.js");
  47. Cu.import("resource://weave/syncCores.js");
  48. Cu.import("resource://weave/stores.js");
  49. Cu.import("resource://weave/trackers.js");
  50.  
  51. Function.prototype.async = Async.sugar;
  52.  
  53. function InputEngine(pbeId) {
  54.   this._init(pbeId);
  55. }
  56. InputEngine.prototype = {
  57.   __proto__: new SyncEngine(),
  58.  
  59.   get name() { return "input"; },
  60.   get displayName() { return "Input History"; },
  61.   get logName() { return "InputEngine"; },
  62.   get serverPrefix() { return "user-data/input/"; },
  63.  
  64.   __store: null,
  65.   get _store() {
  66.     if (!this.__store)
  67.       this.__store = new InputStore();
  68.     return this.__store;
  69.   },
  70.  
  71.   __core: null,
  72.   get _core() {
  73.     if (!this.__core)
  74.       this.__core = new InputSyncCore(this._store);
  75.     return this.__core;
  76.   },
  77.  
  78.   __tracker: null,
  79.   get _tracker() {
  80.     if (!this.__tracker)
  81.       this.__tracker = new InputTracker();
  82.     return this.__tracker;
  83.   }
  84. };
  85.  
  86. function InputSyncCore(store) {
  87.   this._store = store;
  88.   this._init();
  89. }
  90. InputSyncCore.prototype = {
  91.   _logName: "InputSync",
  92.   _store: null,
  93.  
  94.   _commandLike: function FSC_commandLike(a, b) {
  95.     /* Not required as GUIDs for similar data sets will be the same */
  96.     return false;
  97.   }
  98. };
  99. InputSyncCore.prototype.__proto__ = new SyncCore();
  100.  
  101. function InputStore() {
  102.   this._init();
  103. }
  104. InputStore.prototype = {
  105.   _logName: "InputStore",
  106.   _lookup: null,
  107.  
  108.   __placeDB: null,
  109.   get _placeDB() {
  110.     if (!this.__placeDB) {
  111.       let file = Cc["@mozilla.org/file/directory_service;1"].
  112.                  getService(Ci.nsIProperties).
  113.                  get("ProfD", Ci.nsIFile);
  114.       file.append("places.sqlite");
  115.       let stor = Cc["@mozilla.org/storage/service;1"].
  116.                  getService(Ci.mozIStorageService);
  117.       this.__histDB = stor.openDatabase(file);
  118.     }
  119.     return this.__histDB;
  120.   },
  121.   
  122.   _getIDfromURI: function InputStore__getIDfromURI(uri) {
  123.     let pidStmnt = this._placeDB.createStatement("SELECT id FROM moz_places WHERE url = ?1");
  124.     pidStmnt.bindUTF8StringParameter(0, uri);
  125.     if (pidStmnt.executeStep())
  126.       return pidStmnt.getInt32(0);
  127.     else
  128.       return null;
  129.   },
  130.   
  131.   _getInputHistory: function InputStore__getInputHistory(id) {
  132.     let ipStmnt = this._placeDB.createStatement("SELECT input, use_count FROM moz_inputhistory WHERE place_id = ?1");
  133.     ipStmnt.bindInt32Parameter(0, id);
  134.     
  135.     let input = [];
  136.     while (ipStmnt.executeStep()) {
  137.       let ip = ipStmnt.getUTF8String(0);
  138.       let cnt = ipStmnt.getInt32(1);
  139.       input[input.length] = {'input': ip, 'count': cnt};
  140.     }
  141.     
  142.     return input;
  143.   },
  144.  
  145.   _createCommand: function InputStore__createCommand(command) {
  146.     this._log.info("InputStore got createCommand: " + command);
  147.     
  148.     let placeID = this._getIDfromURI(command.GUID);
  149.     if (placeID) {
  150.       let createStmnt = this._placeDB.createStatement("INSERT INTO moz_inputhistory (?1, ?2, ?3)");
  151.       createStmnt.bindInt32Parameter(0, placeID);
  152.       createStmnt.bindUTF8StringParameter(1, command.data.input);
  153.       createStmnt.bindInt32Parameter(2, command.data.count);
  154.       
  155.       createStmnt.execute();
  156.     }
  157.   },
  158.  
  159.   _removeCommand: function InputStore__removeCommand(command) {
  160.     this._log.info("InputStore got removeCommand: " + command);
  161.  
  162.     if (!(command.GUID in this._lookup)) {
  163.       this._log.warn("Invalid GUID found, ignoring remove request.");
  164.       return;
  165.     }
  166.  
  167.     let placeID = this._getIDfromURI(command.GUID);
  168.     let remStmnt = this._placeDB.createStatement("DELETE FROM moz_inputhistory WHERE place_id = ?1 AND input = ?2");
  169.     
  170.     remStmnt.bindInt32Parameter(0, placeID);
  171.     remStmnt.bindUTF8StringParameter(1, command.data.input);
  172.     remStmnt.execute();
  173.     
  174.     delete this._lookup[command.GUID];
  175.   },
  176.  
  177.   _editCommand: function InputStore__editCommand(command) {
  178.     this._log.info("InputStore got editCommand: " + command);
  179.     
  180.     if (!(command.GUID in this._lookup)) {
  181.       this._log.warn("Invalid GUID found, ignoring remove request.");
  182.       return;
  183.     }
  184.  
  185.     let placeID = this._getIDfromURI(command.GUID);
  186.     let editStmnt = this._placeDB.createStatement("UPDATE moz_inputhistory SET input = ?1, use_count = ?2 WHERE place_id = ?3");
  187.     
  188.     if ('input' in command.data) {
  189.       editStmnt.bindUTF8StringParameter(0, command.data.input);
  190.     } else {
  191.       editStmnt.bindUTF8StringParameter(0, this._lookup[command.GUID].input);
  192.     }
  193.     
  194.     if ('count' in command.data) {
  195.       editStmnt.bindInt32Parameter(1, command.data.count);
  196.     } else {
  197.       editStmnt.bindInt32Parameter(1, this._lookup[command.GUID].count);
  198.     }
  199.     
  200.     editStmnt.bindInt32Parameter(2, placeID);
  201.     editStmnt.execute();
  202.   },
  203.  
  204.   wrap: function InputStore_wrap() {
  205.     this._lookup = {};
  206.     let stmnt = this._placeDB.createStatement("SELECT * FROM moz_inputhistory");
  207.     
  208.     while (stmnt.executeStep()) {
  209.       let pid = stmnt.getInt32(0);
  210.       let inp = stmnt.getUTF8String(1);
  211.       let cnt = stmnt.getInt32(2);
  212.  
  213.       let idStmnt = this._placeDB.createStatement("SELECT url FROM moz_places WHERE id = ?1");
  214.       idStmnt.bindInt32Parameter(0, pid);
  215.       if (idStmnt.executeStep()) {
  216.         let key = idStmnt.getUTF8String(0);
  217.         this._lookup[key] = { 'input': inp, 'count': cnt };
  218.       }
  219.     }
  220.  
  221.     return this._lookup;
  222.   },
  223.  
  224.   wipe: function InputStore_wipe() {
  225.     var stmnt = this._placeDB.createStatement("DELETE FROM moz_inputhistory");
  226.     stmnt.execute();
  227.   },
  228.  
  229.   _resetGUIDs: function InputStore__resetGUIDs() {
  230.     let self = yield;
  231.     // Not needed.
  232.   }
  233. };
  234. InputStore.prototype.__proto__ = new Store();
  235.  
  236. function InputTracker() {
  237.   this._init();
  238. }
  239. InputTracker.prototype = {
  240.   _logName: "InputTracker",
  241.  
  242.   __placeDB: null,
  243.   get _placeDB() {
  244.     if (!this.__placeDB) {
  245.       let file = Cc["@mozilla.org/file/directory_service;1"].
  246.                  getService(Ci.nsIProperties).
  247.                  get("ProfD", Ci.nsIFile);
  248.       file.append("places.sqlite");
  249.       let stor = Cc["@mozilla.org/storage/service;1"].
  250.                  getService(Ci.mozIStorageService);
  251.       this.__histDB = stor.openDatabase(file);
  252.     }
  253.     return this.__histDB;
  254.   },
  255.  
  256.   /* 
  257.    * To calculate scores, we just count the changes in
  258.    * the database since the last time we were asked.
  259.    *
  260.    * Each change is worth 5 points.
  261.    */
  262.   _rowCount: 0,
  263.   get score() {
  264.     var stmnt = this._placeDB.createStatement("SELECT COUNT(place_id) FROM moz_inputhistory");
  265.     stmnt.executeStep();
  266.     var count = stmnt.getInt32(0);
  267.     stmnt.reset();
  268.  
  269.     this._score = Math.abs(this._rowCount - count) * 5;
  270.  
  271.     if (this._score >= 100)
  272.       return 100;
  273.     else
  274.       return this._score;
  275.   },
  276.  
  277.   resetScore: function InputTracker_resetScore() {
  278.     var stmnt = this._placeDB.createStatement("SELECT COUNT(place_id) FROM moz_inputhistory");
  279.     stmnt.executeStep();
  280.     this._rowCount = stmnt.getInt32(0);
  281.     stmnt.reset();
  282.     this._score = 0;
  283.   },
  284.  
  285.   _init: function InputTracker__init() {
  286.     this._log = Log4Moz.Service.getLogger("Service." + this._logName);
  287.     this._score = 0;
  288.  
  289.     var stmnt = this._placeDB.createStatement("SELECT COUNT(place_id) FROM moz_inputhistory");
  290.     stmnt.executeStep();
  291.     this._rowCount = stmnt.getInt32(0);
  292.     stmnt.reset();
  293.   }
  294. };
  295. InputTracker.prototype.__proto__ = new Tracker();
  296.